Expand description
libgoblin
libgoblin
is a cross-platform trifecta of binary parsing and loading fun. It supports:
- An ELF32/64 parser, and raw C structs
- A 32/64-bit, zero-copy, endian aware, Mach-o parser, and raw C structs
- A PE32/PE32+ (64-bit) parser, and raw C structs
- A Unix archive parser and loader
Goblin should require at least rustc
1.16, but is developed on stable.
Goblin primarily supports the following important use cases:
-
Core, std-free
#[repr(C)]
structs, tiny compile time, 32/64 (or both) at your leisure -
Type punning. Define a function once on a type, but have it work on 32 or 64-bit variants - without really changing anything, and no macros! See
examples/automagic.rs
for a basic example. -
std
mode. This throws in read and write impls viaPread
andPwrite
, reading from file, convenience allocations, extra methods, etc. This is for clients who can allocate and want to read binaries off disk. -
Endian_fd
. A truly terrible name :laughing: this is for binary analysis like in panopticon which needs to read binaries of foreign endianness, or as a basis for constructing cross platform foreign architecture binutils, e.g. cargo-sym and bingrep are simple examples of this, but the sky is the limit.
Example
use goblin::{error, Object};
use std::path::Path;
use std::env;
use std::fs::File;
use std::io::Read;
fn run () -> error::Result<()> {
for (i, arg) in env::args().enumerate() {
if i == 1 {
let path = Path::new(arg.as_str());
let mut fd = File::open(path)?;
let mut buffer = Vec::new();
fd.read_to_end(&mut buffer)?;
match Object::parse(&buffer)? {
Object::Elf(elf) => {
println!("elf: {:#?}", &elf);
},
Object::PE(pe) => {
println!("pe: {:#?}", &pe);
},
Object::Mach(mach) => {
println!("mach: {:#?}", &mach);
},
Object::Archive(archive) => {
println!("archive: {:#?}", &archive);
},
Object::Unknown(magic) => { println!("unknown magic: {:#x}", magic) }
}
}
}
Ok(())
}
Feature Usage
libgoblin
is engineered to be tailored towards very different use-case scenarios, for example:
- a no-std mode; just simply set default features to false
- a endian aware parsing and reading
- for binary loaders which don’t require this, simply use
elf32
andelf64
(andstd
of course)
For example, if you are writing a 64-bit kernel, or just want a barebones C-like
header interface which defines the structures, just select elf64
, --cfg feature="elf64"
, which will compile without std
.
Similarly, if you want to use host endianness loading via the various from_fd
methods, --cfg feature="std"
, which will not use the byteorder
extern crate, and read the bytes
from disk in the endianness of the host machine.
If you want endian aware reading, and you don’t use default
, then you need to opt in as normal
via endian_fd
Modules
Elf
struct which implements a unified parser that returns a wrapped Elf64
or Elf32
binary.Structs
Hint
Enums
Functions
Start
after reading.bytes
, and returns a Hint